home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
(A)Z
/
(A)Z11.ADF
/
LOGO
/
LOGOSOURCE
/
logonum.c
< prev
next >
Wrap
C/C++ Source or Header
|
2009-11-14
|
5KB
|
248 lines
/* Numeric operations in LOGO.
* In arithmetic operations, the input, which is a character, is
* converted to numeric, the operations are done, and the result is
* converted back to character.
* In all cases, the inputs are freed, and a new output is created.
*
* Copyright (C) 1979, The Children's Museum, Boston, Mass.
* Written by Douglas B. Klunder.
*/
#include <math.h>
#include "logo.h"
nump(x) /* non-LOGO numberp, just for strings */
register struct object *x;
{ /* a number is a series of at least one digit, with an optional
* starting + or -. */
register char ch,*cp;
cp = x->obstr;
if (*cp=='\0') return(0);
if (*cp!='-' && *cp!='+' && (*cp<'0' || *cp>'9') && *cp!='.') return(0);
if ((*cp=='-' || *cp=='+' || *cp=='.') && *(cp+1)=='\0') return(0);
if(*cp=='.' && index(cp+1,'.')) return(0);
cp++;
while ((ch = *cp)!='\0') {
if ((ch<'0'||ch>'9')&&(ch!='e')&&(ch!='E')&&(ch!='.'))
return(0);
if ((ch == 'e') || (ch == 'E')) {
if (index(cp+1,'e') || index(cp+1,'E')
|| index(cp+1,'.')) return(0);
if (((ch = *(cp+1))=='+') || (ch=='-')) cp++;
}
else if (ch == '.') {
if (index(cp+1,'e') || index(cp+1,'E')
|| index(cp+1,'.')) return(0);
}
cp++;
}
return(1);
}
/* Check a STRING object to see if it's an integer string */
isint(x)
register struct object *x;
{
register char ch,*cp;
cp = x->obstr;
while (ch = *cp++)
if ((ch == '.') || (ch == 'e') || (ch == 'E'))
return(0);
return(1);
}
/* convert object (which might be a word of digits) to a number */
struct object *numconv(thing,op)
register struct object *thing;
char *op;
{
register struct object *newthing;
FIXNUM ithing;
NUMBER dthing;
if (thing == 0) ungood(op,thing);
switch (thing->obtype) {
case CONS:
ungood(op,thing);
case INT:
case DUB:
return(thing);
default:
if (!nump(thing)) ungood(op,thing);
if (isint(thing)) {
sscanf(thing->obstr,FIXFMT,&ithing);
newthing = localize(objint(ithing));
} else {
sscanf(thing->obstr,EFMT,&dthing);
newthing = localize(objdub(dthing));
}
}
mfree(thing);
return(newthing);
}
/* convert integer to double */
struct object *dubconv(num)
register struct object *num;
{
NUMBER d;
if (dubp(num)) return(num);
d = num->obint;
mfree(num);
return(localize(objdub(d)));
}
struct object *opp(x) /* Unary - */
register struct object *x;
{
register struct object *ans;
x = numconv(x,"Minus");
if (intp(x)) {
ans = objint(-(x->obint));
} else {
ans = objdub(-(x->obdub));
}
mfree(x);
return(localize(ans));
}
struct object *add(x,y) /* sum */
register struct object *x,*y;
{
FIXNUM iz;
NUMBER dz;
register struct object *z;
x = numconv(x,"Sum");
y = numconv(y,"Sum");
if (!intp(x) || !intp(y)) {
x = dubconv(x);
y = dubconv(y);
}
if (intp(x)) {
iz = (x->obint)+(y->obint);
z = objint(iz);
} else {
dz = (x->obdub)+(y->obdub);
z = objdub(dz);
}
mfree(x);
mfree(y);
return(localize(z));
}
struct object *sub(x,y) /* difference */
register struct object *x,*y;
{
FIXNUM iz;
NUMBER dz;
register struct object *z;
x = numconv(x,"Difference");
y = numconv(y,"Difference");
if (!intp(x) || !intp(y)) {
x = dubconv(x);
y = dubconv(y);
}
if (intp(x)) {
iz = (x->obint)-(y->obint);
z = objint(iz);
} else {
dz = (x->obdub)-(y->obdub);
z = objdub(dz);
}
mfree(x);
mfree(y);
return(localize(z));
}
struct object *mult(x,y) /* product */
register struct object *x,*y;
{
FIXNUM iz;
NUMBER dz;
register struct object *z;
x = numconv(x,"Product");
y = numconv(y,"Product");
if (!intp(x) || !intp(y)) {
x = dubconv(x);
y = dubconv(y);
}
if (intp(x)) {
iz = (x->obint)*(y->obint);
z = objint(iz);
} else {
dz = (x->obdub)*(y->obdub);
z = objdub(dz);
}
mfree(x);
mfree(y);
return(localize(z));
}
divzero(name)
char *name;
{
pf1("%s can't divide by zero.\n",name);
errhand();
}
struct object *div(x,y) /* quotient */
register struct object *x,*y;
{
NUMBER dz;
x = numconv(x,"Quotient");
y = numconv(y,"Quotient");
x = dubconv(x);
y = dubconv(y);
if (y->obdub == 0.0) divzero("Quotient");
dz = (x->obdub)/(y->obdub);
mfree(x);
mfree(y);
if (dz == (NUMBER)(FIXNUM)dz) {
return(localize(objint((FIXNUM)dz)));
} else {
return(localize(objdub(dz)));
}
}
struct object *rem(x,y) /* remainder */
register struct object *x,*y;
{
FIXNUM iz;
register struct object *z;
x = numconv(x,"Remainder");
y = numconv(y,"Remainder");
if (!intp(x)) ungood("Remainder",x);
if (!intp(y)) ungood("Remainder",y);
if (y->obint == 0) divzero("Remainder");
iz = (x->obint)%(y->obint);
z = objint(iz);
mfree(x);
mfree(y);
return(localize(z));
}
struct object *torf(pred)
int pred;
{
if (pred) return(true());
return(false());
}
struct object *greatp(x,y) /* greaterp */
register struct object *x,*y;
{
int iz;
x = numconv(x,"Greaterp");
y = numconv(y,"Greaterp");
if